package br.com.saeng2D.util;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ResourceBundle;

import javax.swing.JOptionPane;
import javax.xml.parsers.SAXParserFactory;

import br.com.saeng2D.objeto.ponto.Ponto;
import br.com.saeng2D.superficie.Superficie;
import br.com.saeng2D.xml.ManipuladorXML;

import com.sun.org.apache.xerces.internal.parsers.SAXParser;

//Utilitario da aplicacao
//Ler as preferencias e configuracoes do arquivo preferencias_e_configuracoes.properties
//Todos os metodos sao estaticos
public class Util {
	private static ResourceBundle bundle;

	static {
		bundle = ResourceBundle.getBundle("preferencias_e_configuracoes");
	}

	// Construtor
	private Util() {
	}

	public static Vetor criarVetor(int xOrigem, int yOrigem, int x2, int y2) {
		int x = x2 - xOrigem;
		int y = yOrigem - y2;
		return new Vetor(x, y);
	}

	public static Vetor criarVetor(P2D p2dOrigem, P2D p2d) {
		int x = p2d.x - p2dOrigem.x;
		int y = p2dOrigem.y - p2d.y;
		return new Vetor(x, y);
	}

	public static Vetor criarVetor(Ponto pontoOrigem, Ponto ponto) {
		int x = ponto.getX() - pontoOrigem.getX();
		int y = pontoOrigem.getY() - ponto.getY();
		return new Vetor(x, y);
	}
	
	public static void mensagem(String msg) {
		mensagem(null, msg);
	}

	public static void mensagem(Component componente, String msg) {
		JOptionPane.showMessageDialog(componente, msg);
	}

	public static int confirmar(Component componente, String msg) {
		return JOptionPane.showConfirmDialog(componente, msg, Util.getString("label_atencao"), JOptionPane.OK_OPTION);
	}

	public static boolean estarNuloOuVazio(Object objeto) {
		return objeto == null || objeto.toString().trim().length() == 0;
	}

	public static String getString(String chave) {
		return bundle.getString(chave);
	}

	public static Boolean getBoolean(String chave) {
		return new Boolean(bundle.getString(chave));
	}

	public static int getInt(String chave) {
		return Integer.parseInt(bundle.getString(chave));
	}

	public static double getDouble(String chave) {
		return Double.parseDouble(bundle.getString(chave));
	}
	
	public static Color getCor(String chave) {
		int r = getInt(chave + "R");
		int g = getInt(chave + "G");
		int b = getInt(chave + "B");
		return new Color(r, g, b);
	}

	// Centralizar um componente em relacao ao video ou outro componente
	public static void centralizar(Component componente, Component pai) {
		if(pai == null) {
			Dimension video = Toolkit.getDefaultToolkit().getScreenSize();
			Dimension compo = componente.getSize();
			componente.setLocation((video.width - compo.width) / 2, (video.height - compo.height) / 2 - 40);
		} else {
			Point point = pai.getLocationOnScreen();
			Dimension video = pai.getSize();
			Dimension compo = componente.getSize();
			componente.setLocation((video.width - compo.width) / 2 + point.x, (video.height - compo.height) / 2 + point.y);
		}
	}

	public static boolean ehNumeroInteiro(String string) {
		try {
			Integer.parseInt(string);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static String getDiretorioAplicacao() {
		File file = new File(".");
		String caminho = file.getAbsolutePath();
		int pos = caminho.lastIndexOf(".");
		return caminho.substring(0, pos);
	}

	public static void abrirArquivo(Superficie superficie, File file) {
		try {
			InputStream is = new FileInputStream(file);
			SAXParserFactory factory = SAXParserFactory.newInstance();
			javax.xml.parsers.SAXParser parser = factory.newSAXParser();
			ManipuladorXML xml = new ManipuladorXML();
			parser.parse(file, xml);
			superficie.limparSuperficie();
			superficie.recuperarObjeto(xml);
			superficie.setArquivo(file);
			superficie.setAlterado(false);
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// Uma coordenada deve sobrepor uma determinada linha da grade
	public static void normalizar(P2D p2d) {
		if (p2d == null) {
			return;
		}
		P2D ponto = normalizar(p2d.x, p2d.y);
		p2d.x = ponto.x;
		p2d.y = ponto.y;
	}

	// Uma coordenada deve sobrepor uma determinada linha da grade
	public static void normalizar(Ponto ponto_) {
		if (ponto_ == null) {
			return;
		}
		P2D ponto = normalizar(ponto_.getX(), ponto_.getY());
		ponto_.setX(ponto.x);
		ponto_.setY(ponto.y);
	}
	
	// Uma coordenada deve sobrepor uma determinada linha da grade
	public static P2D normalizar(int x, int y) {
		int ladoGd = Util.getInt("largura_grade");
		int metade = ladoGd / 2;
		int restoX = x % ladoGd;
		int restoY = y % ladoGd;

		if (restoX != 0) {
			if (restoX <= metade) {
				x -= restoX;
			} else {
				x -= restoX;
				x += ladoGd;
			}
		}

		if (restoY != 0) {
			if (restoY <= metade) {
				y -= restoY;
			} else {
				y -= restoY;
				y += ladoGd;
			}
		}

		if (x <= 0) {
			x = ladoGd;
		}
		
		if (y <= 0) {
			y = ladoGd;
		}
		
		return new P2D(x, y);
	}

	private static void criarPrologoXML(PrintWriter pw) {
		pw.println("<?xml version='1.0' encoding='UTF-8'?>");
		pw.println("<saeng2d xmlns='saeng2d.com.br'>");
	}
	
	private static void finalizarXML(PrintWriter pw) {
		pw.println("</saeng2d>");
	}
	
	public static void salvarArquivo(Superficie superficie, File file) {
		try {
			String extensao = ".xml";
			if (file.getCanonicalPath().endsWith(extensao)) {
				extensao = "";
			}
			PrintWriter pw = new PrintWriter(file.getAbsolutePath() + extensao);
			criarPrologoXML(pw);
			superficie.salvarXML("", pw);
			finalizarXML(pw);
			pw.close();
			superficie.setArquivo(file);
			superficie.setAlterado(false);
			mensagem(superficie.getFormularioPrincipal(), "Arquivo salvo!");
		} catch (Exception e) {
			e.printStackTrace();
			mensagem(superficie.getFormularioPrincipal(),
					"Erro ao tentar salvar o arquivo!\r\n" + file);
		}
	}
}